﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CartItemController.cs" company="DST Nexdox">
//   Copyright (c) DST Nexdox. All rights reserved.
// </copyright>
// <summary>
//   Defines the CartItemController type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace UnityWeb.Controllers
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web.Mvc;
  using Entities;
  using Logging;
  using ServiceInterfaces;
  using UnityWeb.Filters;
  using UnityWeb.Models.CartItem;

  [AuthorizeLoggedInUser]
  public class CartItemController : BaseController
  {
    private const Int32 PageSize = 10;

    private readonly ICartItemService cartItemService;
    private readonly IExportFileService exportFileService;

    public CartItemController(
        ICartItemService cartItemService,
        IExportFileService exportFileService,
        ILogger logger)
      : base(logger)
    {
      this.cartItemService = cartItemService;
      this.exportFileService = exportFileService;
    }

    [AuthorizeLoggedInUser(Roles = "Admin,dstadmin,Governor")]
    public ActionResult Index(Int32 page = 1, Boolean isAjaxCall = false)
    {
      var cartItemsViewModel = new CartItemsViewModel();
      String cartId = CartItem.GetCartId(this.HttpContext);

      PagedResult<CartItem> cartItems = this.cartItemService.GetCartItems(cartId, page, PageSize);

      cartItemsViewModel.AddCartItems(cartItems);

      if (isAjaxCall)
      {
        return this.PartialView("_PagedCartItemResults", cartItemsViewModel);
      }

      if (cartItemsViewModel.CartTotal == 0)
      {
        return this.RedirectToAction("Index", "Dashboard");
      }

      return this.View(cartItemsViewModel);
    }

    public ActionResult AddGridToCart(String grid)
    {
      String cartId = CartItem.GetCartId(this.HttpContext);

      AddToCartResults addToCartResults = this.cartItemService.AddGrid(
        this.HttpContext.User.Identity.Name,
        cartId,
        grid);

      CartItemSummaryViewModel cartItemSummaryViewModel = this.GetCartSummary();
      cartItemSummaryViewModel.DocumentWarningsViewModel.DocumentsAlreadyCheckedOut = String.Join(",", addToCartResults.DocumentsAlreadyCheckedOut);
      cartItemSummaryViewModel.DocumentWarningsViewModel.DocumentAddToBasketErrors = String.Empty;
      cartItemSummaryViewModel.DocumentWarningsViewModel.BasketContainsDocumentFromAnotherManCo = String.Join(",", addToCartResults.DocumentsWithDifferentManCoToBasket);

      return this.PartialView("_CartSummary", cartItemSummaryViewModel);
    }

    [HttpPost]
    public ActionResult AddToCart(AddCartItemsViewModel addCartItemsViewModel)
    {
      if (addCartItemsViewModel.AddCartItemViewModel == null)
      {
        return this.PartialView("_CartSummary", new CartItemSummaryViewModel());
      }

      IEnumerable<String> selectedDocumentIds =
        addCartItemsViewModel.AddCartItemViewModel.Where(d => d.Selected).Select(vm => vm.DocumentId);

      String cartId = CartItem.GetCartId(this.HttpContext);

      AddToCartResults addToCartResults = this.cartItemService.AddItems(
        this.HttpContext.User.Identity.Name,
        cartId,
        selectedDocumentIds);

      CartItemSummaryViewModel cartItemSummaryViewModel = this.GetCartSummary();

      cartItemSummaryViewModel.DocumentWarningsViewModel.DocumentsAlreadyCheckedOut = String.Join(",", addToCartResults.DocumentsAlreadyCheckedOut);
      cartItemSummaryViewModel.DocumentWarningsViewModel.DocumentAddToBasketErrors = String.Empty;
      cartItemSummaryViewModel.DocumentWarningsViewModel.BasketContainsDocumentFromAnotherManCo = String.Join(",", addToCartResults.DocumentsWithDifferentManCoToBasket);

      return this.PartialView("_CartSummary", cartItemSummaryViewModel);
    }

    [HttpPost]
    public ActionResult RemoveFromCart(RemoveCartItemsViewModel removeCartItemsViewModel)
    {
      String cartId = CartItem.GetCartId(HttpContext);

      foreach (var document in removeCartItemsViewModel.RemoveCartItemViewModel.Where(d => d.Selected))
      {
        this.cartItemService.RemoveItem(document.DocumentId, cartId);
      }

      CartItemSummaryViewModel cartItemSummaryViewModel = this.GetCartSummary();

      return this.PartialView("_CartSummary", cartItemSummaryViewModel);
    }

    public ActionResult ClearCart()
    {
      String cartId = CartItem.GetCartId(HttpContext);
      this.cartItemService.ClearCart(cartId);

      return this.RedirectToAction("Index", "Dashboard");
    }

    [HttpPost]
    public ActionResult ExportBasketToZip(String cartId)
    {
      IList<CartItem> cartItems = this.cartItemService.GetCart(cartId);

      List<String> documentIds = (from c in cartItems select c.Document.DocumentId).ToList();

      String zipFilePath = this.exportFileService.ExportToZip(documentIds);

      this.cartItemService.ClearCart(cartId);

      return this.Json(new { file = zipFilePath });
    }

    [HttpPost]
    public ActionResult ExportDocumentsToZip(List<String> documentIds)
    {
      var zipFilePath = this.exportFileService.ExportToZip(documentIds);

      String cartId = CartItem.GetCartId(HttpContext);

      documentIds.ForEach(x => this.cartItemService.RemoveItem(x, cartId));

      return this.Json(new { file = zipFilePath });
    }

    public ActionResult Download(String file)
    {
      return this.File(file, System.Net.Mime.MediaTypeNames.Application.Zip, "ZippedDocuments.zip");
    }

    [ChildActionOnly]
    public ActionResult Summary()
    {
      CartItemSummaryViewModel cartItemSummaryViewModel = this.GetCartSummary();
      return this.PartialView("_CartSummary", cartItemSummaryViewModel);
    }

    private CartItemSummaryViewModel GetCartSummary()
    {
      String cartId = CartItem.GetCartId(HttpContext);
      Int32 numberOfCartItems = this.cartItemService.GetNumberOfItemsInCart(cartId);

      var cartItemSummaryViewModel = new CartItemSummaryViewModel(numberOfCartItems);
      return cartItemSummaryViewModel;
    }
  }
}
